use serde::{Deserialize, Serialize};
use chrono::{DateTime, Utc};

/// 用户信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    pub id: i64,
    pub username: String,
    pub password_hash: String,
    pub salt: String,
    pub home_directory: String,
    pub max_storage_size: i64,
    pub is_active: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub last_login: Option<DateTime<Utc>>,
    pub login_count: i32,
}

/// 用户权限
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserPermission {
    pub id: i64,
    pub user_id: i64,
    pub permission_type: PermissionType,
    pub path_pattern: String,
    pub granted: bool,
    pub created_at: DateTime<Utc>,
}

/// 权限类型
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum PermissionType {
    Read,
    Write,
    Delete,
    Admin,
}

impl PermissionType {
    pub fn to_string(&self) -> String {
        match self {
            PermissionType::Read => "READ".to_string(),
            PermissionType::Write => "WRITE".to_string(),
            PermissionType::Delete => "DELETE".to_string(),
            PermissionType::Admin => "ADMIN".to_string(),
        }
    }
    
    pub fn from_string(s: &str) -> Self {
        match s.to_uppercase().as_str() {
            "READ" => PermissionType::Read,
            "WRITE" => PermissionType::Write,
            "DELETE" => PermissionType::Delete,
            "ADMIN" => PermissionType::Admin,
            _ => PermissionType::Read, // 默认读取权限
        }
    }
}

/// FTP会话
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Session {
    pub id: i64,
    pub user_id: i64,
    pub session_token: String,
    pub client_ip: String,
    pub client_port: u16,
    pub data_port: Option<u16>,
    pub passive_port: Option<u16>,
    pub transfer_mode: TransferMode,
    pub current_directory: String,
    pub created_at: DateTime<Utc>,
    pub last_activity: DateTime<Utc>,
    pub is_active: bool,
}

/// 传输模式
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum TransferMode {
    Active,
    Passive,
}

impl TransferMode {
    pub fn to_string(&self) -> String {
        match self {
            TransferMode::Passive => "PASV".to_string(),
            TransferMode::Active => "PORT".to_string(),
        }
    }
    
    pub fn from_string(s: &str) -> Self {
        match s.to_uppercase().as_str() {
            "PASV" => TransferMode::Passive,
            "PORT" => TransferMode::Active,
            _ => TransferMode::Passive, // 默认被动模式
        }
    }
}

/// 传输日志
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransferLog {
    pub id: i64,
    pub session_id: i64,
    pub operation: String,
    pub file_path: String,
    pub file_size: Option<i64>,
    pub bytes_transferred: i64,
    pub transfer_speed: Option<f64>,
    pub status: String,
    pub error_message: Option<String>,
    pub started_at: DateTime<Utc>,
    pub completed_at: Option<DateTime<Utc>>,
}

/// FTP响应码
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum FtpResponseCode {
    // 1xx - 肯定初步回复
    DataConnectionAlreadyOpen = 125,
    FileStatusOk = 150,
    
    // 2xx - 肯定完成回复
    CommandOk = 200,
    SystemType = 215,
    ServiceReady = 220,
    ServiceClosing = 221,
    DataConnectionOpen = 225,
    ClosingDataConnection = 226,
    EnteringPassiveMode = 227,
    UserLoggedIn = 230,
    RequestedFileActionOk = 250,
    PathnameCreated = 257,
    
    // 3xx - 肯定中间回复
    UserNameOk = 331,
    NeedAccount = 332,
    NeedPassword = 334,
    
    // 4xx - 暂时否定完成回复
    ServiceNotAvailable = 421,
    DataConnectionNotOpen = 425,
    ConnectionClosed = 426,
    InvalidUsernameOrPassword = 430,
    HostUnavailable = 434,
    FileActionNotTaken = 450,
    LocalError = 451,
    InsufficientStorage = 452,
    
    // 5xx - 永久否定完成回复
    SyntaxError = 500,
    ParameterSyntaxError = 501,
    CommandNotImplemented = 502,
    BadSequence = 503,
    CommandNotImplementedForParameter = 504,
    NotLoggedIn = 530,
    NeedAccountForStoring = 532,
    FileNotFound = 550,
    PageTypeUnknown = 551,
    ExceededStorageAllocation = 552,
    FileNameNotAllowed = 553,
}

/// FTP响应
#[derive(Debug, Clone)]
pub struct FtpResponse {
    pub code: FtpResponseCode,
    pub message: String,
}

impl FtpResponse {
    pub fn new(code: FtpResponseCode, message: &str) -> Self {
        Self {
            code,
            message: message.to_string(),
        }
    }
    
    pub fn is_positive_preliminary(&self) -> bool {
        matches!(self.code as u16, 100..=199)
    }
    
    pub fn is_positive_completion(&self) -> bool {
        matches!(self.code as u16, 200..=299)
    }
    
    pub fn is_positive_intermediate(&self) -> bool {
        matches!(self.code as u16, 300..=399)
    }
    
    pub fn is_transient_negative(&self) -> bool {
        matches!(self.code as u16, 400..=499)
    }
    
    pub fn is_permanent_negative(&self) -> bool {
        matches!(self.code as u16, 500..=599)
    }
}
